﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PetGo
{
    class Pattern
    {
        public static Dictionary<long, Pattern> patterns = new Dictionary<long, Pattern>();
        // 5*5 key und 0-18 x und 0-18 y
        public long key;
        //public string filename;
        public static long divpos = 282429536481*3; 
        // alle Patternkeys der Antworten
        public Dictionary<long, PatternCon> answer = new Dictionary<long, PatternCon>();
        public Pattern(long thekey)
            //, string thefilename)
        {
            key = thekey;
            //filename = thefilename;
            if (!patterns.ContainsKey(key))
            {
                patterns[key] = this;
            } 
        }
        public void insertAnswer(Board board, int nextpos, bool won, string thefilename, int lastpos)
        {

            long key = getpatternkey(board, nextpos, lastpos);
            if (key == 0)
            {
                if (answer.Count == 0)
                {
                    patterns.Remove(this.key);
                }
                return;
            }
            if (!answer.ContainsKey(key))
            {
                answer[key] = new PatternCon();
            }
            answer[key].addCon(won);
        }
        
        public static long getpatternkey(Board board, int pos, int lastpos)
        {
            long theReturn = 0;
            int stones = 0;
            int dx = board.getx0(pos) - 2;
            int dy = board.gety0(pos) - 2;
            if (dx < 0) dx = 0;
            if (dx > board.myboardsize - 5) dx = board.myboardsize - 5;
            if (dy < 0) dy = 0;
            if (dy > board.myboardsize - 5) dy = board.myboardsize - 5;
            long t = 1;
            for (int y = dy; y < dy + 5; ++y)
            {
                for (int x = dx; x < dx + 5; ++x)
                {
                    if (board.myGroupPosition.ContainsKey(x+y*board.myboardsize))
                    {
                        if (board.myGroup[board.myGroupPosition[x + y * board.myboardsize]].myColor != board.mytoMove)
                        //    if (board.myGroup[board.myGroupPosition[x + y * board.myboardsize]].myColor == color.black)
                        {
                            theReturn += t;
                            stones++;
                            if (stones > 8)
                            //if (stones > 3 && board.getdistance_int(pos, lastpos) > 12 || stones > 8)
                            {
                                return 0;
                            }
                        }
                        else
                        {
                            theReturn += 2*t;
                            stones++;
                            if (stones > 8)
                            //if (stones > 3 && board.getdistance_int(pos, lastpos) > 12 || stones > 8)
                            {
                                return 0;
                            }
                        }
                    }
                    t *= 3;
                }
            }
            theReturn += pos * t;
            return theReturn;
        }
        public static void writepatternandwait(long key)
        {
            long temp = key;

            Console.WriteLine(temp / divpos);
            temp -= divpos * (temp / divpos); 
            for (int y = 0; y < 5; ++y)
            {
                for (int x = 0; x < 5; ++x)
                {
                    Console.Write(temp % 3);
                    temp /= 3;
                }
                Console.WriteLine();
            }
            while (Console.ReadKey().ToString() == "") ;

        }
        public static void buildPattern(Game game)
        {
            int rx = 0;
            int ry = 0;
            int pos = 0;
            int lastpos = 0;
            int countit = 0;
            color winner = color.black;
            List<string> theFiles = Sgf.getsgfs();
            //string path = @"C:\Users\peter\Documents\syn_user\Go\Progames\ChoChikun\2003-08-07.sgf";
            foreach (string path in theFiles)
            {
                ++countit;
#if debug
                Console.WriteLine((double)countit / theFiles.Count);
#endif
                List<int> hist = Sgf.sgfHistorie(path, out winner);
                Pattern thePattern = null;
                //Board theboard = game.myBoard.Copy();
                try
                {
                    hist.Insert(0, -1);
                    for (int r = 0; r < 8; ++r)
                    {
                        Board theboard = game.myBoard.Copy();
                        foreach (int pos1 in hist)
                        {
                            lastpos = pos;
                            if (pos1 > -1)
                            {
                                // rotation
                                switch (r)
                                {
                                    //90
                                    case 1:
                                    case 5:
                                        rx = theboard.getx0(pos1) - theboard.myboardsize / 2;
                                        if (r > 4) rx = -rx;
                                        ry = theboard.gety0(pos1) - theboard.myboardsize / 2;
                                        pos = (ry + theboard.myboardsize / 2) + (-rx + theboard.myboardsize / 2) * theboard.myboardsize;
                                        break;
                                    //180
                                    case 2:
                                    case 6:
                                        rx = theboard.getx0(pos1) - theboard.myboardsize / 2;
                                        ry = theboard.gety0(pos1) - theboard.myboardsize / 2;
                                        if (r > 4) rx = -rx;
                                        pos = (-rx + theboard.myboardsize / 2) + (-ry + theboard.myboardsize / 2) * theboard.myboardsize;
                                        break;
                                    //270
                                    case 3:
                                    case 7:
                                        rx = theboard.getx0(pos1) - theboard.myboardsize / 2;
                                        ry = theboard.gety0(pos1) - theboard.myboardsize / 2;
                                        if (r > 4) rx = -rx;
                                        pos = (-ry + theboard.myboardsize / 2) + (rx + theboard.myboardsize / 2) * theboard.myboardsize;
                                        break;
                                    default:
                                        rx = theboard.getx0(pos1) - theboard.myboardsize / 2;
                                        ry = theboard.gety0(pos1) - theboard.myboardsize / 2;
                                        if (r > 4) rx = -rx;
                                        pos = (rx + theboard.myboardsize / 2) + (ry + theboard.myboardsize / 2) * theboard.myboardsize;
                                        break;
                                }
                            }
                            else
                            {
                                pos = pos1;
                            }
                            if (thePattern != null)
                            {
                                thePattern.insertAnswer(theboard, pos, winner == theboard.mytoMove, path, lastpos);
                                //++countit;
                            }

                            //, path);
                            if (pos > -1)
                            {
                                theboard.place(pos, theboard.mytoMove);
                                theboard.mytoMove = theboard.getopponent(theboard.mytoMove);
                            }
                            //getRot(pos, out xrot, out yrot, out rotpos, game.myBoard);
                            long key = getpatternkey(theboard, pos, lastpos);
                            

                            if (key == 0)
                            {
                                thePattern = null;
                                continue;
                            }
                            //if (pos == 41)
                            //{
                            //    theboard.writeboardandwait();
                            //}
                            new Pattern(key);
                            thePattern = patterns[key];
                        }
                    }
                }
                catch
                {
                    ;
                }
            }

            //Dictionary<long, Pattern> theDic = new Dictionary<long, Pattern>();
            //foreach(Pattern thepat in patterns.Values)
            //{
            //    int count = 0;
            //    Dictionary<long, PatternCon> theAns = new Dictionary<long, PatternCon>();
            //    foreach(long theanswerkey in thepat.answer.Keys)
            //    {
            //        if (thepat.answer[theanswerkey].vorkommen < 2)
            //        {
            //            ;
            //            continue;
            //        }
            //        theAns[theanswerkey] = thepat.answer[theanswerkey];
            //        count += theAns[theanswerkey].vorkommen;
            //    }
            //    if (count > 2)
            //    {
            //        thepat.answer = theAns;
            //        theDic[thepat.key] = thepat;
            //    }
            //}
            //patterns = new Dictionary<long, Pattern>(theDic);
            foreach(long l in patterns.Keys.ToList())
            {
                int sum = 0;
                int vorsum = 0;
                foreach(long a in patterns[l].answer.Keys.ToList())
                {
                    sum += patterns[l].answer[a].wins;
                    vorsum += patterns[l].answer[a].vorkommen;
                }
                //if (vorsum < 2)
                //{
                //    patterns.Remove(l);
                //}
                //else
                //{
                    foreach (long a in patterns[l].answer.Keys.ToList())
                    {
                        if (patterns[l].answer[a].wins < patterns[l].answer[a].vorkommen / 4)
                        {
                            patterns[l].answer.Remove(a);
                        }
                    }
                //}
                if (patterns.ContainsKey(l) && patterns[l].answer.Count == 0)
                {
                    patterns.Remove(l);
                }

            }
        }
    }
}
